#include "common.h"
#include "tcp.hpp"
#include "HandelSerDser.h"
#include "HttpsResponse.h"
#include "HandelSql.h"

using namespace MY_TCP;
// 主页面
std::string index_html()
{

  std::string index_html;
  std::string common_js;
  std::string styles_css;
  std::ifstream ifs;
  ifs.open("./project/index.html", std::ios::in);

  if (!ifs.is_open())
  {
    return "NOT FOUND";
  }
  std::string str;
  while (getline(ifs, str))
  {
    index_html += str;
  }
  ifs.close();

  std::string http_response;
  http_response += respondHtml(index_html);
  return http_response;
}
std::string result_html(std::string)
{

  std::string result_html;
}
// 其他页面
std::string handler(std::string goal_local)
{
  goal_local = "./project" + goal_local;
  std::ifstream ifs;
  ifs.open(goal_local.c_str(), std::ios::in);
  if (!ifs.is_open())
  {
    return "NOT FOUND";
  }
  std::string str;
  std::string tmp_html;
  while (std::getline(ifs, str))
  {
    tmp_html += str;
  }
  ifs.close();
  // std::cout << goal_local << "\n";
  std::string http_response;
  if (goal_local.find(".html") != std::string::npos)
    http_response += respondHtml(tmp_html);
  else if (goal_local.find(".css") != std::string::npos)
    http_response += respondCss(tmp_html);
  else if (goal_local.find(".js") != std::string::npos)
    http_response += respondJs(tmp_html);
  return http_response;
}
// 接受链接
void *link_http(void *argv)
{
  int fd = *(int *)argv;
  delete (int *)argv;

  char arr[1024];
  int size = recv(fd, arr, sizeof(arr), 0);
  std::string str = arr;
  int begin = str.find(' ');
  std::string http_method = str.substr(0, str.find(' '));
  std::string http_path = str.substr(begin + 1, str.find(' ', begin + 1) - begin - 1);

  // std::cout << http_method << http_method.length() <<"\n";
  // std::cout << http_path << http_path.length() << "\n";

  if (http_method == std::string("GET"))
  {
    std::cout << str << "\n";
    if (http_path == std::string("/"))
    {
      std::string http_response = index_html();
      send(fd, http_response.c_str(), http_response.size(), 0);
    }
    else
    {
      std::string http_response = handler(http_path);
      send(fd, http_response.c_str(), http_response.size(), 0);
    }
  }
  else if (http_method == std::string("POST"))
  {
    std::cout << str << "\n";
    int pos = str.find("Content-Length: ") + 16;
    std::string len = str.substr(pos, str.find(" ", pos));

    std::string body = str.substr(str.find("\r\n\r\n") + 4, std::stoi(len));
    // std::cout << body << "\n";
    Student student;
    Teacher teacher;
    College college;
    Course course;
    Admin admin;

    if (http_path.find("add"))
    {
      // 序列化
      if (http_path.find("student") != std::string::npos)
        student.deserialize(body);
      if (http_path.find("teachers") != std::string::npos)
        teacher.deserialize(body);
      if (http_path.find("departments") != std::string::npos)
        college.deserialize(body);
      if (http_path.find("courses") != std::string::npos)
        course.deserialize(body);
      if (http_path.find("admins") != std::string::npos)
        admin.deserialize(body);

      // 交给SQL处理
      MYSQL *mysql_i = mysql_init(nullptr);
      if (mysql_i == nullptr)
        std::cout << "init errno" << "\n";
      if (mysql_real_connect(mysql_i, "localhost", "lazy", "12345678", "StudentManage", 3306, NULL, 0) == nullptr)
        std::cout << "connect errno" << "\n";
      mysql_set_character_set(mysql_i, "utf8");
      HandelSQL handelsql;
      if (http_path.find("student") != std::string::npos)
      {
        if (http_path.find("add") != std::string::npos)
        {
          std::string sql = "insert into student values";
          sql += student.strTosql();
          int res = mysql_query(mysql_i, sql.c_str());
          if (res != 0)
            std::cout << "query errror" << "\n";
          else
            std::cout << "query success" << "\n";
        }
        else if (http_path.find("query") != std::string::npos && body == "{}")
        {
          std::string sql = "select * from student";
          int res = mysql_query(mysql_i, sql.c_str());
          if (res != 0)
            std::cout << "query errror" << "\n";
          else
            std::cout << "query success" << "\n";
          MYSQL_RES *result = mysql_store_result(mysql_i);
          int rows = mysql_num_rows(result);
          int cols = mysql_num_fields(result);
          // 2.3 解析数据 -- 获取表中列名 -- 一般不用，仅仅是为了测试代码的完整性
          std::string out;
          MYSQL_FIELD *fields = mysql_fetch_fields(result);
          for (int i = 0; i < cols; i++)
          {
            std::ostringstream oss;
            oss << fields[i].name;
            out += oss.str();
            out += "\t";
          }
          out += "\n";
          // 2.4 解析数据 -- 获取表中的数据 -- 重要
          for (int i = 0; i < rows; i++)
          {
            MYSQL_ROW line = mysql_fetch_row(result); // 获取完整的一行记录（默认从前往后）
            for (int j = 0; j < cols; j++)
            {
              std::ostringstream oss;
              oss << line[j];
              out += oss.str();
              out += "\t";
            }
            out += "\n";
            std::string http_response = respondHtml(out);
            send(fd, http_response.c_str(), http_response.size(), 0);
          }
          std::cout << out << "\n";
          // free(result); // 释放内存空间
        }
        else
        {
          std::cout << "查询" << "\n";
        }
      }
      mysql_close(mysql_i);

      if (http_path.find("teachers") != std::string::npos)
        ;
      if (http_path.find("departments") != std::string::npos)
        ;
      if (http_path.find("courses") != std::string::npos)
        ;
      if (http_path.find("admins") != std::string::npos)
        ;
      // 反序列化
    }
  }
  close(fd);
  return nullptr;
}
void Usage(std::string command)
{
  std::cout << command << " port" << std::endl;
}
int main(int args, char *argv[])
{
  if (args != 2)
  {
    std::cerr << "use error" << std::endl;
    Usage(argv[0]);
    exit(1);
  }
  int port = atoi(argv[1]);
  int sock_fd = TCP_SOCK::Sock();
  TCP_SOCK::Bind(sock_fd, port);
  TCP_SOCK::Listen(sock_fd, 5);
  while (true)
  {
    int new_fd = TCP_SOCK::Accept(sock_fd);
    pthread_t pid;
    int *fd = new int(new_fd);
    pthread_create(&pid, nullptr, link_http, (void *)fd);
  }
  return 0;
}